package com.wanger.swa.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wanger.swa.domain.myEnum.DataSourceEnum;
import com.wanger.swc.exception.BusEx;
import com.wanger.swc.util.mybatisplus.MyWrapper;
import com.wanger.swc.util.validation.MyVerifyUtil;
import com.wanger.swa.convert.DataSourceConvert;
import com.wanger.swa.dto.dataSource.inf.DataSourceDispatch;
import com.wanger.swa.dto.dataSource.query.DataSourceQuery;
import com.wanger.swa.dto.dataSource.req.DataSourceAddReq;
import com.wanger.swa.dto.dataSource.req.DataSourceUpdateReq;
import com.wanger.swa.dto.dataSource.resp.DataSourceActualContentResp;
import com.wanger.swa.dto.dataSource.resp.DataSourceResp;
import com.wanger.swa.domain.po.DataSourcePO;
import com.wanger.swa.domain.mapper.DataSourceMapper;
import com.wanger.swa.dto.dataSource.resp.SupportTypeResp;
import com.wanger.swa.service.ise.DataSourceService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.anyline.metadata.type.DatabaseType;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * @Author: wanger
 * @Date: 2024/9/15 12:52
 * @Description: 数据源
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class DataSourceServiceImpl extends ServiceImpl<DataSourceMapper, DataSourcePO> implements DataSourceService {

    private final DataSourceConvert dataSourceConvert;
    private final DataSourceDispatch dataSourceDispatch;

    @Override
    public DataSourceResp addDataSource(DataSourceAddReq addDTO) {
        DataSourcePO dataSource = dataSourceConvert.toSaveEntity(addDTO);
        if (CollUtil.isNotEmpty(this.list(MyWrapper.create(DataSourcePO.class)
                .eq(dataSource::getName)
        ))) BusEx.throwEx("数据源名称不能重复！");
        this.save(dataSource);
        this.registerDataSources(dataSource);
        return dataSourceConvert.toDetailsDTO(dataSource);
    }

    @Override
    public DataSourceResp updateDataSource(DataSourceUpdateReq updateDTO) {
        DataSourcePO dataSource = dataSourceConvert.toUpdateEntity(updateDTO);
        this.updateById(dataSource);
        dataSource.setUpdateTime(null);
        this.registerDataSources(dataSource);
        return dataSourceConvert.toDetailsDTO(dataSource);
    }

    @Override
    public DataSourceResp getOneDataSource(String id) {
        DataSourcePO dataSource = this.getById(id);
        return dataSourceConvert.toDetailsDTO(dataSource);
    }

    @Override
    public IPage<DataSourceResp> pageDataSource(DataSourceQuery query) {
        IPage<DataSourcePO> page = this.page(
                new Page<>(query.getCurrent(), query.getSize()),
                MyWrapper.create(DataSourcePO.class)
                        .like(query::getName)
                        .eq(query::getType)
                        .eq(query::getContentType)
                        .orderByDesc(DataSourcePO::getCreateTime));
        return dataSourceConvert.toPageDTO(page);
    }

    @Override
    public List<DataSourceResp> listDataSource(DataSourceQuery query) {
        return this.pageDataSource(query).getRecords();
    }

    @Override
    public void deleteDataSource(String id) {
        this.removeById(id);
    }

    @Override
    public List<SupportTypeResp> getSupportType() {
        return dataSourceDispatch.getSupportType();
    }

    @Override
    public void dataVerification(DataSourceAddReq addDTO) {
        dataSourceDispatch.verify(BeanUtil.copyProperties(addDTO, DataSourcePO.class));
    }

    @Override
    public DataSourceActualContentResp getDataSourceById(String id) {
        MyVerifyUtil.nullVerify(id, "数据源id不能为空！");
        DataSourcePO po = this.getById(id);
        MyVerifyUtil.nullVerify(po, "数据源不存在！");
        DataSourceResp dto = dataSourceConvert.toDetailsDTO(po);
        DataSourceActualContentResp resp = BeanUtil.copyProperties(dto, DataSourceActualContentResp.class);
        resp.setDataObj(dataSourceDispatch.getContent(po));
        return resp;
    }

    @Override
    public void registerAllDataSources() {
        List<DataSourcePO> list = this.list(MyWrapper.create(DataSourcePO.class)
                .eq(DataSourcePO::getType, DataSourceEnum.STRUCTURE.getValue()));
        list.forEach(this::registerDataSources);
    }

    @Override
    public void registerDataSources(DataSourcePO po) {
        MyVerifyUtil.nullVerify(po, "数据源不能为空！");
        MyVerifyUtil.nullVerify(po::getType);
        if (DataSourceEnum.STRUCTURE.getValue().equals(po.getType())) {
            DatabaseType dbType = DatabaseType.valueOf(po.getContentType());
            MyVerifyUtil.nullVerify(dbType, "数据源类型【{}】不支持！", po.getContentType());
            dataSourceDispatch.registeredDataSource(dbType, po.getId(), po.getName(), po.getUrl(), po.getUsername(), po.getPassword());
        }
    }
}
